package com.hjb.service.impl.com;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.hjb.service.com.ComVerifyCodeService;
import com.hjb.service.domain.commsglog.ComMsgLog;
import com.hjb.service.domain.comverifycode.ComVerifyCode;
import com.hjb.service.domain.comverifycode.ComVerifyCodeExample;
import com.hjb.service.domain.recharge.SiteAuthCode;
import com.hjb.service.domain.recharge.SiteAuthCodeExample;
import com.hjb.service.mapper.ComMsgLogMapper;
import com.hjb.service.mapper.ComVerifyCodeMapper;
import com.hjb.service.mapper.SiteAuthCodeMapper;
import com.hjb.service.utils.DateUtil;
import com.hjb.service.utils.SendSmsUtil;
import com.hjb.service.utils.SmsUtil;

@Service
public class ComVerifyCodeServiceImpl implements ComVerifyCodeService {

	private Logger log = LoggerFactory.getLogger(ComVerifyCodeServiceImpl.class);

	private static final int SHORT_MSG_INTERVAL = 1;

	private ExecutorService executorService = Executors.newFixedThreadPool(5);

	private Random random = new Random();

	@Autowired
	private ComVerifyCodeMapper comVerifyCodeMapper;

	@Autowired
	private SiteAuthCodeMapper siteAuthCodeMapper;

	@Autowired
	private ComMsgLogMapper comMsgLogMapper;

	private boolean isEnable = true;

	private String smsSwith = /* "huyi" */"shuyuan";

	@Override
	public List<ComVerifyCode> selectByExample(ComVerifyCodeExample example) {
		return comVerifyCodeMapper.selectByExample(example);
	}

	@Override
	public int insertComVerifyCode(ComVerifyCode comVerifyCode) {
		return comVerifyCodeMapper.insertSelective(comVerifyCode);
	}

	@Override
	public boolean sendShorMsgVerifyCode(ComVerifyCode comVerifyCode) {
		ComVerifyCodeExample example = new ComVerifyCodeExample();
		example.createCriteria().andObjectIdEqualTo(comVerifyCode.getObjectId())
				.andChannelEqualTo(comVerifyCode.getChannel()).andBizEqualTo(comVerifyCode.getBiz());
		List<ComVerifyCode> ret = comVerifyCodeMapper.selectByExample(example);
		/**
		 * 由于每次生产验证码,只更新update_time,所以必须按照updatetime,才能防止每分钟只能调用一次
		 */
		if (CollectionUtils.isEmpty(ret) || DateUtil.isExpired(ret.get(0).getUpdateTime(), SHORT_MSG_INTERVAL)) {
			/**
			 * 两种情况会生产新的验证码 a 数据库没有记录,没有验证码 b
			 * 数据库有记录,但按照验证码的create_time来算,已经超过30分钟的
			 */
			if (CollectionUtils.isEmpty(ret) || DateUtil.isExpired(ret.get(0).getCreateTime(), 30)) {// 没有发送过
				if (CollectionUtils.isEmpty(ret)) {
					comVerifyCode.setVerifyCode(generateRandCode());
					comVerifyCode.setUpdateTime(new Date());
					comVerifyCodeMapper.insertSelective(comVerifyCode);
				} else {
					ComVerifyCode temp = new ComVerifyCode();
					temp.setId(ret.get(0).getId());
					temp.setVerifyCode(generateRandCode());
					temp.setUpdateTime(new Date());
					temp.setCreateTime(new Date());
					comVerifyCodeMapper.updateByPrimaryKeySelective(temp);
					comVerifyCode.setVerifyCode(temp.getVerifyCode());
				}
			} else {
				comVerifyCode.setVerifyCode(ret.get(0).getVerifyCode());
				ComVerifyCode temp = new ComVerifyCode();
				temp.setId(ret.get(0).getId());
				temp.setVerifyCode(ret.get(0).getVerifyCode());
				temp.setUpdateTime(new Date());
				comVerifyCodeMapper.updateByPrimaryKeySelective(temp);
			}

			ComMsgLog comVerifyCodeLog = new ComMsgLog();
			String msgDes = /** 签名为空 **/
					"" + "您的验证码是：" + comVerifyCode.getVerifyCode() + "。请不要把验证码泄露给其他人。";
			comVerifyCodeLog.setContent(msgDes);
			comVerifyCodeLog.setPhoneNum(comVerifyCode.getObjectId());
			comVerifyCodeLog.setChannel(comVerifyCode.getChannel());
			comVerifyCodeLog.setBiz(comVerifyCode.getBiz());
			comVerifyCodeLog.setType(comVerifyCode.getType());
			comVerifyCodeLog.setCode(comVerifyCode.getVerifyCode());
			comVerifyCodeLog.setIp(comVerifyCode.getIp());
			return sendShortMsg(comVerifyCodeLog);
		}
		return false;
	}

	private String generateRandCode() {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < 6; i++) {
			sb.append(random.nextInt(10));
		}
		return sb.toString();
	}

	public Boolean sendShortMsg(final ComMsgLog comMsgLog) {
		log.info("isEnable:[" + isEnable + "],smsSwith:[" + smsSwith + "]");
		if (!Boolean.TRUE.equals(isEnable)) {
			log.info("短信通道被禁用了,所以发不出短信,需要修改下相应配置文件即可 " + comMsgLog);
			return true;
		}

		executorService.execute(new Runnable() {

			@Override
			public void run() {
				// 1 发短信
				try {
					String ret = null;
					if ("huyi".equals(smsSwith)) {
						ret = SmsUtil.sendSmsHuyi(comMsgLog.getPhoneNum(), comMsgLog.getContent());
						comMsgLog.setSupplier("huyi");
					} else if ("shuyuan".equals(smsSwith)) {
						ret = SendSmsUtil.sendSms(comMsgLog.getPhoneNum(), comMsgLog.getContent());
						comMsgLog.setSupplier("shuyuan");
					}

					log.info(ret);
					if (ret != null && ret.length() > 20) {
						ret = ret.substring(0, 19);
					}

					comMsgLog.setReturnCode(ret);
					// 2 存记录
					comMsgLogMapper.insert(comMsgLog);
				} catch (Exception e) {
					log.error("", e);
				}
			}
		});
		return true;
	}

	@Override
	public int sendShorMsgVerifyCode(ComMsgLog comMsgLog, Integer type) {
		String code = generateRandCode();
		String msgDes = 
				"您的验证码为"+code+"，5分钟内有效，请尽快验证。";
		comMsgLog.setContent(msgDes);
		sendShortMsg(comMsgLog);
		SiteAuthCode siteAuthCode = new SiteAuthCode();
		siteAuthCode.setAuthCode(code);
		siteAuthCode.setMobile(comMsgLog.getPhoneNum());
		siteAuthCode.setCodeType(type);
		siteAuthCode.setCreateTime(new Date());
		siteAuthCode.setUpdateTime(new Date());

		SiteAuthCodeExample example = new SiteAuthCodeExample();
		example.createCriteria().andMobileEqualTo(comMsgLog.getPhoneNum()).andCodeTypeEqualTo(type);

		siteAuthCodeMapper.deleteByExample(example);
		siteAuthCodeMapper.insert(siteAuthCode);

		return 200;
	}

	@Override
	public int verifyCode(String mobile, String smsCode, Integer type) throws ParseException {

		SiteAuthCodeExample example = new SiteAuthCodeExample();
		example.createCriteria().andMobileEqualTo(mobile).andCodeTypeEqualTo(type);
		List<SiteAuthCode> list = siteAuthCodeMapper.selectByExample(example);

		if (list != null & list.size() == 1) {
			SiteAuthCode siteAuthCode = list.get(0);
			if (smsCode.equals(siteAuthCode.getAuthCode())) {

				Date create = siteAuthCode.getCreateTime();
//				SimpleDateFormat dfs = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				Date now = new Date();
//				Date end = dfs.parse("2004-03-26 13:31:40");
				long between = (now.getTime() - create.getTime()) / 1000;// 除以1000是为了转换成秒
				long min = between / 60;
				
				if(min>5){
					return 2;
				}

				return 1;
			} else {
				return 0;
			}
		}

		return 0;
	}

}
